#include "utils.h"
#include "entity.h"
#include "tire.h"

// 添加epoll监听
int addEpoll(int epoll_fd, int fd){
	struct epoll_event event_socket;
	event_socket.events = EPOLLIN;			/* 读取 */
	event_socket.data.fd = fd;	/* 指定文件描述符 */
	epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event_socket);

    return 0;
}


/**
 * @brief 字符串去除首尾空格和换行
 * @param str 
*/
void trim(char *str) {
    int start = 0, end = strlen(str) - 1;

    // 找到第一个非空格和非换行符的位置
    while (isspace(str[start]) || str[start] == '\n')
        start++;

    // 找到最后一个非空格和非换行符的位置
    while (end > start && (isspace(str[end]) || str[end] == '\n'))
        end--;

    // 将字符串前移
    memmove(str, str + start, end - start + 1);

    // 在字符串末尾添加空字符
    str[end - start + 1] = '\0';
}




/**
 * @brief 判断输入是否合法
 * @param parameter 会改变参数内容，最终为合法命令的第二个参数内容
 * @return 合法返回1，非法返回0
*/
int handleCommand(unsigned short *command, char *parameter){

    // 去头尾空格
    trim(parameter);
    
    // 单命令不用判断后面参数
    int isSingleCmd = query(parameter, strlen(parameter));
    
    // 如果是多参数命令？
    if(isSingleCmd == PWD || isSingleCmd == LS){
        *command = isSingleCmd;
        return 1;
    }

    // 判断输入是否合法
	char cmd[10];//存储命令
    char text[1024];//存储命令相关文本

	//以空格作为分隔，将提取到的第一个令牌存储到token中
    char *token = strtok(parameter, " ");
    if(token == NULL){
        return 0;
    }
	//将第一个令牌复制到cmd数组中
    strcpy(cmd, token);

	//继续获取下一个令牌
    token = strtok(NULL, " ");
    if(token == NULL){
        return 0;
    }
	//将第二个令牌复制到text数组中
    strcpy(text, token);

	
    int ret = query(cmd, strlen(cmd));
    if(ret == -1){
        return 0;
    }

    // 合法命令需要赋值给command
    *command = ret;

    strcpy(parameter, text);
    return 1;
}



void handleError(unsigned short command){
    switch (command){
        case DATA:
            break;

        case LOGIN:
            // 
            break;

        case REGISTER:
            // 
            break;

        case CD:
            // 切换目录
            break;

        case LS:
            // 返回ls内容
            break;

        case PWD:
            // 返回当前目录
            
            
            break;

        case PUT_FILE:
            // 上传文件
            break;

        case GET_FILE:
            // 下载文件
            printf("GET_FILE失败\n");
            break;

        case RM:
            // 删除文件
            break;

        case MKDIR:
            // 创建目录
            break;

    }
}

/**
 * @brief 根据key从config文件中返回需要的value值
 * @author yhx
*/
int getValueByKeyFromConfig(char *key, char *value) {
    FILE *file = fopen("config/config.ini", "r");
	while (1)
	{
		char line[100];
		memset(line,0,sizeof(line));
		// 读一行数据
		char *res = fgets(line, sizeof(line), file);
		if (res == NULL)
		{
			char buf[] = "没有要找的内容 \n";
			memcpy(value, buf, strlen(buf));
			return -1;
		}
		// 处理数据
		char *line_key = strtok(line, "=");
		if (strcmp(key, line_key) == 0)
		{
			// 要找的内容
			char *line_value = strtok(NULL, "=");
			memcpy(value, line_value, strlen(line_value) - 1);
			return 0;
		}
	}

	return 0;
}

/**
 * @brief 用来接收服务端的ls命令返回值并进行输出到客户端
 * @author yhx
 * 
*/
void printListDirectoryContent(int net_fd) {
    // 先收集总长度
    int len = 0;
    recv(net_fd,&len,sizeof(int),0);
    // printf("printLS接收到了len: %d\n",len);
    char res[255] = {0};
    // 如果len!=0,则接收结果字符串，如果为0，意味着没有任何内容，就不接收
    if (len == 0) return;
    recv(net_fd,res,len,0);
    printf("%s\n",res);
}



/**
 * @brief 接收并打印当前目录
 * @author 杨明铎
*/
void printCurrentDirectory(int net_fd){
    unsigned int frameLength;
    char buf[1024];
    memset(buf, 0, sizeof buf);
    recv(net_fd, &frameLength, sizeof frameLength, MSG_WAITALL);
    recv(net_fd, buf, frameLength, MSG_WAITALL);
    printf("%s\n", buf);

}


/**
 * @brief 从配置文件中获取ip
 * @author yhx
*/
char *getIpFromConfig() {
   char *ip = (char *)calloc(100,sizeof(char));
   getValueByKeyFromConfig("ip",ip);
   return ip;
}

/**
 * @brief 从配置文件中获取port
 * @author yhx
*/
char *getPortFromConfig() {
   char *port = (char *)calloc(100,sizeof(char));
   getValueByKeyFromConfig("port",port);
   return port;
}